

use ring::{digest::{Context, SHA256}, digest};
use ring::{aead}; // AES_256_GCM
use base64::engine::general_purpose;
use base64::alphabet::{Alphabet, STANDARD};
use base64::{DecodeError, Engine};
use ring::aead::{BoundKey, Nonce, NONCE_LEN};
use ring::error::Unspecified;
use ring::rand::SystemRandom;
/* sha256 编码 */
pub fn sha256_hash(message: &str) -> String {
    let binding = digest::digest(&SHA256, message.as_bytes());
    let date_by = binding.as_ref();
    return hex::encode(date_by);
}

/* base64 加密 */
pub fn base64_encode_byte(bytes: &[u8]) -> String {
    let gp = general_purpose::GeneralPurpose::new(&STANDARD, general_purpose::NO_PAD);
    return gp.encode(bytes);
}
/* base64 加密 */
pub fn base64_encode(bytes: &str) -> String {
    let gp = general_purpose::GeneralPurpose::new(&STANDARD, general_purpose::NO_PAD);
    return gp.encode(bytes);
}

/* base64 解码 */
pub fn base64_decode(data: &str) -> Result<String, DecodeError> {
    let gp = general_purpose::GeneralPurpose::new(&STANDARD, general_purpose::NO_PAD);
    let decode_bytes = gp.decode(data)?;
    return match std::str::from_utf8(&*decode_bytes) {
        Ok(d) => { Ok(d.to_string()) }
        Err(e) => { Err(DecodeError::InvalidPadding) }
    };
}


pub fn key_length16(key: &[u8]) -> [u8; 16] {
    let len = key.len();
    let mut key_vec: Vec<u8> = Vec::new();
    for i in 0..16 {
        if i >= len {
            key_vec.push(0);
        } else {
            key_vec.push(key[i])
        }
    }
    // println!("key_length： {:?}", key_vec);
    let keyu8: [u8; 16] = key_vec.try_into().unwrap();
    return keyu8;
}

pub fn aes_encode(key: &[u8], content: &[u8]) -> String {
    let unboundkey = aead::UnboundKey::new(&aead::AES_128_GCM, &key_length16(key)).unwrap();
    let mut sealingkey = aead::SealingKey::new(unboundkey, MyNonce {});
    let aad = aead::Aad::empty();
    let mut inout = content.to_vec();
    let result = aead::SealingKey::seal_in_place_append_tag(&mut sealingkey, aad, &mut inout);
    // println!("aes_encode content: {:?}", inout);
    return hex::encode(inout);
}

pub fn aes_encode_str(key: &str, content: &str) -> String {
    let mut content = content.as_bytes().to_vec();
    aes_encode(key.as_bytes(), &mut content)
}

pub fn aes_decode(key: &[u8], content: &[u8]) -> String{
    let unboundkey = aead::UnboundKey::new(&aead::AES_128_GCM, &key_length16(key)).unwrap();
    let mut sealingkey = aead::OpeningKey::new(unboundkey, MyNonce {});
    let aad = aead::Aad::empty();
    let mut inout = hex::decode("9df96a90c251375b8b930c18ff7ed6d6675633d17ebcced999a0543d71e5c56e76bbc39e8d6c8f9214937e29af50").unwrap();
    println!("inout1: {:?}", inout);
    let result = aead::OpeningKey::open_in_place(&mut sealingkey, aad, &mut inout);

    return std::str::from_utf8_mut(result.unwrap()).unwrap().to_string();


}


struct MyNonce {}

impl aead::NonceSequence for MyNonce {
    fn advance(&mut self) -> Result<Nonce, Unspecified> {
        Ok(aead::Nonce::assume_unique_for_key(<[u8; 12]>::try_from("123456789012".as_bytes())?))
    }
}

// fn encrypt(data: &[u8], key: &[u8], nonce: &[u8; 12]) -> Result<Vec<u8>, aead::Unspecified> {
//     let unbound_key = aead::UnboundKey::new(&aead::AES_256_GCM, key)?;
//     // let less_safe_key = aead::LessSafeKey::new(unbound_key);
//     let mut encryptor = aead::SealingKey::new(unbound_key, &aead::AES_256_GCM);
//
//     let nonce = aead::Nonce::assume_unique_for_key(*nonce);
//     let mut ciphertext = Vec::with_capacity(encryptor.algorithm().max_overhead() + data.len());
//     encryptor.seal_in_place(&nonce, b"", data, &mut ciphertext)?;
//     Ok(ciphertext)
// }

pub fn test_ring() {
    // sha256_hash("我像只鱼儿在你的河畔，是谁在你守候的茭白月光。柳下闻夜曲起舞轻红霓，我去你入狱踩断缝纫机。");
    // let result = base64_encode("我像只鱼儿在你的河畔，是谁在你守候的茭白月光。柳下闻夜曲起舞轻红霓，我去你入狱踩断缝纫机。");
    // println!("result: {}", result);
    // let result2 = base64_decode("5oiR5YOP5Y+q6bG85YS/5Zyo5L2g55qE5rKz55WU77yM5piv6LCB5Zyo5L2g5a6I5YCZ55qE6Iyt55m95pyI5YWJ44CC5p+z5LiL6Ze75aSc5puy6LW36Iie6L2757qi6ZyT77yM5oiR5Y675L2g5YWl54ux6Lip5pat57yd57qr5py644CC");
    // println!("result: {:?}", result2);

    // let data:[u8;30] = [230, 136, 145, 229, 142, 187, 228, 189, 160, 229, 133, 165, 231, 139, 177, 232, 184, 169, 230, 150, 173, 231, 188, 157, 231, 186, 171, 230, 156, 186];
    // println!("data: {}", std::str::from_utf8(&data).unwrap());

    let b = "F1A5BEEF00112233".as_bytes();
    println!("b: {:?}", b);
    let mut content = "我去你入狱踩断缝纫机".as_bytes().to_vec();
    println!("content: {:?}", content);
    println!("打印数据： {}", aes_encode(b, "我去你入狱踩断缝纫机".as_bytes()));
    let b2 = "F1A5BEEF00112233".as_bytes();
    aes_decode(b2, "9df96a90c251375b8b930c18ff7ed6d6675633d17ebcced999a0543d71e5".as_bytes());
}




























